<?php
/**
 * Created by PhpStorm.
 * User: helloxingtongshi
 * Date: 2016-06-02
 * Time: 16:39
 */
/*calendar.class.php日历原文件
声明一个日历类，名称为calendar，用来显示一个可以设置日期的日历
*/
class calendar{
    private $year;//当前年月日
    private $month;
    private $start_weekday;//当月的第一天对应的是周几，作为当月遍历日期的开始
    private $days;
//    构造方法，用来初始化一些日期属性
    function __construct()
    {
    //    如果用户没有设置年份数，则使用当前系统时间的年份
        $this->year=isset($_GET['year'] )? $_GET['year']:date("Y");//当前的年
        $this->month=isset($_GET['month'] )? $_GET['month']:date("m");//当前的月
    //    通过具体的年份和月份，利用date（）函数的w参数获取当月第一天对应的是周几
        $this->start_weekday=date("w",mktime(0,0,0,$this->month,1,$this->year));
        //获取当月天数
        //$this->days = cal_days_in_month(CAL_GREGORIAN, $this->month, $this->year);

        $this->days=date("t",mktime(0,0,0,$this->month,1,$this->year));//通过具体的年份和月份，利用date（）函数的t参数获取当月的天数
    }
//    魔术方法用于打印整个日历
    function __toString()//()是快速获取对象的字符串信息的便捷方式
    {   $out="";
        $out .='<table align="center">';//日历一表格形式打印
        $out .=$this->chagedate();//调用内部私有方法用于用户自己设置日期
        $out .=$this->weeklist();//调用内部私有方法打印“周”列表
        $out .=$this->dayslist();//调用内部私有方法打印“日”列表
        $out .='</table>';
        return $out;//返回整个日列，输出需要的全部字符串
    }
//    内部调用的私有方法，用于输出周列表
    private function weeklist(){
        $week=array('日','一','二','三','四','五','六');
        $out="";
        $out .='<tr>';
        for($i=0;$i<count($week);$i++){
            $out .='<th class="fontb">'.$week[$i].'</th>';//第一行以表格<th>形式输出周列表
        }
        $out .='</tr>';
        return $out;//返回周列表字符串
    }
//    内部调用的私有方法，用于输出日列表
    private function dayslist(){
        $out="";
        $out .='<tr>';
//        输出空格，当前月第一天前面要空出来
        for($j=0;$j<$this->start_weekday;$j++) {
            $out .= '<td>&nbsp;</td>';//第一行以表格<th>形式输出周列表
        }
//            将当月的所有日期循环遍历除了，如果是当前日期，为其设置深色背景
         for ($k=1;$k<=$this->days;$k++){
            $j++;
            if($k==date('d')){
                $out .= '<td class="fontb">'.$k.'</td>';
            }else{
                $out .='<td>'.$k.'</td>';
            }
            if ($j%7==0){ //每输出7个日期就换一行
                $out .='</tr><tr>';
            }
         }
        while($j%7!==0){ //遍历完日期后，将后面的空格补齐
            $out .='<td>&nbsp;</td>';
            $j++;
        }
        $out .='</tr>';
        return $out;//返回周列表字符串
    }
//    内部调用的私有方法，用于处理当前年份的上一年需要的数据
    private function prevyear($year,$month){
       $year=$year-1;
        if($year<1970){//如果设置的年份小于1970
            $year=1970;//年份设置最小值是1970
        }
        return "year={$year}& month={$month}";//返回最终的年份和月份设置参数
    }
//    内部调用的私有方法，用于处理当前月份的上一月份需要的数据
    private function prevmonth($year,$month){
        $year=$year-1;
        if($year<1970){//如果设置的年份小于1970
            $year=1970;//年份设置最小值是1970
            $month=12;
        }else{
            $month--;
        }

        return "year={$year}&month={$month}";//返回最终的年份和月份设置参数
    }
//    内部调用的私有方法，用于处理前年份的下一年需要的数据
    private function nextyear($year,$month){
        $year=$year+1;
        if($year<2038){//如果设置的年份大于2038
            $year=2038;//年份设置最大值是2038
        }
        return "year={$year}&month={$month}";//返回最终的年份和月份设置参数
    }
//    内部调用的私有方法，用于处理前月份的下一月需要的数据
    private function nextmonth($year,$month){
        if ($month==12){
            $year++;
        if($year<2038){//如果设置的年份大于2038
            $year=2038;//年份设置最大值是2038
        }
        $month=1;//设置月份为下一年的第一个月
         }else{
            $month++;
        }
        return "year={$year}&month={$month}";//返回最终的年份和月份设置参数
    }
//    内部调用的私有方法，用于调整年份和月份的设置
    private function chagedate($url="calendar.index.php"){
        $out="";
        $out .='<tr>';
        $out .='<td><a href="'.$url.'?'.$this->prevyear($this->year,$this->month).'">'.'<<'.'</a></td>';
        $out .='<td><a href="'.$url.'?'.$this->prevmonth($this->year,$this->month).'">'.'<<'.'</a></td>';
        $out .='<td colspan="3">';
        $out .='<form>';
        $out .='<select name="year" onchange="window.location=\''.$url.'?year=\'+this.options[selectedIndex].value+\'&month='.$this->month.'\'">';
        for ($sy=1970;$sy<=2038;$sy++){
            $selected=($sy==$this->year)?"selected":"";
            $out .='<option '.$selected.' value="'.$sy.'">'.$sy.'</option>';
        }
        $out .='</select>';
        $out .='<select name="month" onchange="window.location=\''.$url.'?year='.$this->year.'&month=\'+this.options[selectedIndex].value">';
        for ($sm=1;$sm<=12;$sm++){
            $selected=($sm==$this->month)?"selected":"";
            $out .='<option '.$selected.' value="'.$sm.'">'.$sm.'</option>';
        }
        $out .='</select>';
        $out .='</form>';
        $out .='</td>';
        $out .='<td><a href="'.$url.'?'.$this->nextyear($this->year,$this->month).'">'.'>>'.'</a></td>';
        $out .='<td><a href="'.$url.'?'.$this->nextmonth($this->year,$this->month).'">'.'>>'.'</a></td>';
        $out .='</tr>';
        return $out;//返回电子日期的表单
    }
}
?>